package com.adt.studioms.web.controller.user;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ModelAndView;

import com.adt.studioms.StudiomsApplication;
import com.adt.studioms.api.OperatorAPI;
import com.adt.studioms.om.Operator;
import com.asao.baseware.core.security.ITrustedPassport;
import com.asao.baseware.core.util.DateUtil;
import com.asao.baseware.core.web.controller.EntityCommand;
import com.asao.baseware.core.web.controller.EntityFormController;

public class OperatorController extends EntityFormController<OperatorCommand> {
    OperatorAPI opAPI;

    class OperatorValidator implements Validator {

        public boolean supports(Class clazz) {
            return clazz.equals(OperatorCommand.class);
        }

        public void validate(Object target, Errors errors) {
            OperatorCommand cmd = (OperatorCommand) target;
            
            if (StringUtils.isEmpty(cmd.getCode())) {
                errors.rejectValue("code", "operator.codeIsRequired", "Code is required");
            }
            
            if (StringUtils.isEmpty(cmd.getRole())) {
                errors.rejectValue("role", "operator.roleIsRequired", "Role is required");
            }
            
            if (StringUtils.isEmpty(cmd.getLoginName())) {
                errors.rejectValue("loginName", "operator.loginNameIsRequired", "Login name is required");
            }
            
            if (StringUtils.isEmpty(cmd.getPassword())) {
                errors.rejectValue("password", "operator.passwordIsRequired", "Password is required");
            } else if (StringUtils.isEmpty(cmd.getConfirmPassword())) {
                errors.rejectValue("confirmPassword", "operator.confirmPasswordIsRequired", "Confirm password is required");
            } else if (!cmd.getPassword().equals(cmd.getConfirmPassword())) {
                errors.rejectValue("confirmPassword", "operator.confirmPasswordDoesNotMatch", "Confirm password does nt match");
            }
            
            if (StringUtils.isNotBlank(cmd.getDateOfBirth())) {
                if (DateUtil.parseDate(cmd.getDateOfBirth())==null) {
                    errors.rejectValue("dateOfBirth", "operator.dateOfBirthIsNotValid", "Date of birth is not valid");
                }
            }
            
            if (StringUtils.isNotBlank(cmd.getDateOfMarriage())) {
                if (DateUtil.parseDate(cmd.getDateOfMarriage())==null) {
                    errors.rejectValue("dateOfMarriage", "operator.dateOfMarriage", "Date of marriage is not valid");
                }
            }
        }

    }

    public OperatorController() {
        super();
        opAPI = StudiomsApplication.instance.getApiRegistry().lookupAPI(ITrustedPassport.instance, OperatorAPI.class);

        setCommandClass(OperatorCommand.class);
        setValidator(new OperatorValidator());
    }

    protected void publishEntity(long id, OperatorCommand command) {
        Operator op = opAPI.get(id);
        if (op!=null) {
            command.setId(op.getId());
            command.setCode(op.getCode());
            command.setRole(op.getRole());
            command.setName(op.getName());
            command.setLoginName(op.getLoginName());
            command.setAddress(op.getAddress());
            command.setPhone(op.getPhone());
            if (op.getDateOfBirth()!=null) {
                String sDOB = new SimpleDateFormat("dd/MM/yyyy").format(op.getFormattedDateofBirth());
                command.setDateOfBirth(sDOB);
            }
            if (op.getDateOfMarriage()!=null) {
                String sDOM = new SimpleDateFormat("dd/MM/yyyy").format(op.getFormattedDateofMarriage());
                command.setDateOfMarriage(sDOM);
            }
        }
    }

    protected void createEntity(OperatorCommand command, BindException errors) {
        Operator op = opAPI.createOperator(command.getCode(), 
                                           command.getRole(),
                                           command.getName(),
                                           command.getLoginName(),
                                           command.getPassword(),
                                           command.getAddress(), 
                                           command.getPhone(),
                                           command.dateOfBirth(),
                                           command.dateOfMarriage()) ;
        command.setId(op.getId());
    }

    protected void updateEntity(OperatorCommand command, BindException errors) {
        Operator op = opAPI.get(command.getId());
        if (op!=null) {
            op.setCode(command.getCode());
            op.setRole(command.getRole());
            op.setName(command.getName());
            op.setLoginName(command.getLoginName());
            op.setAddress(command.getAddress());
            op.setPhone(command.getPhone());
            op.setDateOfBirth(command.dateOfBirth());
            op.setDateOfMarriage(command.dateOfMarriage());
            opAPI.update(op);
        }
    }

    protected void deleteEntity(OperatorCommand command, BindException errors) {
        opAPI.delete(command.getId());
    }

    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = super.handleRequestInternal(request, response);
        mv.addObject("roles", new String[] {"USER", "ADMIN"});
        
        return mv;
    }
}

class OperatorCommand extends EntityCommand {
    String code;
    String role = Operator.USER;
    String loginName;
    String password;
    String confirmPassword;
    String address;
    String phone;
    String dateOfBirth;
    String dateOfMarriage;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(String dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
    
    public Long dateOfBirth() {
        Date date = DateUtil.parseDate(dateOfBirth);
        return date!=null ? date.getTime() : null;
    }

    public String getDateOfMarriage() {
        return dateOfMarriage;
    }

    public void setDateOfMarriage(String dateOfMarriage) {
        this.dateOfMarriage = dateOfMarriage;
    }
    
    public Long dateOfMarriage() {
        Date date = DateUtil.parseDate(dateOfMarriage);
        return date!=null ? date.getTime() : null;
    }
}
